/*************************************************************************
 * Nuvoton Electronics Corporation confidential
 *
 * Copyright (c) 2008 by Nuvoton Electronics Corporation
 * All rights reserved
 * 
 * FILENAME
 *     nuc900_pci.h
 *
 * VERSION
 *     1.0
 *
 * DESCRIPTION
 *     NUC900 PCI library header file
 *
 * DATA STRUCTURES
 *
 *
 * FUNCTIONS
 *
 *
 * HISTORY
 *     2008.08.12		Created
 *
 * REMARK
 *     None
 **************************************************************************/

#ifndef _NUC900_PCI_H
#define _NUC900_PCI_H


#define PCI_TYPE0_ADDRESSES 				6
#define PCI_INVALID_VENDORID                0xFFFF
#define PCI_INVALID_DEVICEID                0xFFFF

#define PCI_MAX_BUS                         255
#define PCI_MAX_DEVICES                     32
#define PCI_MAX_FUNCTION                    8

#define PCI_DEVICE_OFFSET                   0x800

typedef VOID (PCI_CB_FUNC_T)(VOID);

typedef struct _PCI_COMMON_CONFIG {
    USHORT  VendorID;                   // (ro)
    USHORT  DeviceID;                   // (ro)
    USHORT  Command;                    // Device control
    USHORT  Status;
    UCHAR   RevisionID;                 // (ro)
    UCHAR   ProgIf;                     // (ro)
    UCHAR   SubClass;                   // (ro)
    UCHAR   BaseClass;                  // (ro)
    UCHAR   CacheLineSize;              // (ro+)
    UCHAR   LatencyTimer;               // (ro+)
    UCHAR   HeaderType;                 // (ro)
    UCHAR   BIST;                       // Built in self test

    union {
        struct _PCI_HEADER_TYPE_0 {
            UINT32   BaseAddresses[PCI_TYPE0_ADDRESSES];
            UINT32   CIS;
            USHORT  SubVendorID;
            USHORT  SubSystemID;
            UINT32   ROMBaseAddress;
            UINT32   Reserved2[2];

            UCHAR   InterruptLine;      //
            UCHAR   InterruptPin;       // (ro)
            UCHAR   MinimumGrant;       // (ro)
            UCHAR   MaximumLatency;     // (ro)
        } type0;
    } u;

    UCHAR   DeviceSpecific[192];

} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;

typedef struct _PCI_DEV_INFO {
    UINT32 nSlotIndex;
    USHORT  VendorID;
    USHORT  DeviceID;
    PPCI_COMMON_CONFIG pCfg;
    UINT32 MemBase;
    UINT32 MemLen;
    UINT32 IOBase;
    UINT32 IOLen;
    UINT32 Command;
    UINT32 Latency;
    UINT32 SecondaryLatency;
    PCI_CB_FUNC_T *fnPCICallback;
} PCI_DEV_INFO, *PPCI_DEV_INFO;


typedef struct _PCI_DEV_INFO_EX {
    PCI_DEV_INFO pciDevice;
    UINT32        dwBusNumberBase;
    UINT32        dwBusNumberLength;
} PCI_DEV_INFO_EX, *PPCI_DEV_INFO_EX;


//
// Bit encodings for PCI_COMMON_CONFIG.Command
//

#define PCI_ENABLE_IO_SPACE                 0x0001
#define PCI_ENABLE_MEMORY_SPACE             0x0002
#define PCI_ENABLE_BUS_MASTER               0x0004
#define PCI_ENABLE_SPECIAL_CYCLES           0x0008
#define PCI_ENABLE_WRITE_AND_INVALIDATE     0x0010
#define PCI_ENABLE_VGA_COMPATIBLE_PALETTE   0x0020
#define PCI_ENABLE_PARITY                   0x0040  // (ro+)
#define PCI_ENABLE_WAIT_CYCLE               0x0080  // (ro+)
#define PCI_ENABLE_SERR                     0x0100  // (ro+)
#define PCI_ENABLE_FAST_BACK_TO_BACK        0x0200  // (ro)

//
// Bit encodings for  PCI_COMMON_CONFIG.HeaderType
//

#define PCI_MULTIFUNCTION                   0x80
#define PCI_DEVICE_TYPE                     0x00
#define PCI_BRIDGE_TYPE                     0x01

//
// Bit encodes for PCI_COMMON_CONFIG.u.type0.BaseAddresses
//

#define PCI_ADDRESS_IO_SPACE                0x00000001  // (ro)
#define PCI_ADDRESS_MEMORY_TYPE_MASK        0x00000006  // (ro)
#define PCI_ADDRESS_MEMORY_PREFETCHABLE     0x00000008  // (ro)

#define PCI_ADDRESS_IO_ADDRESS_MASK         0xfffffffc
#define PCI_ADDRESS_MEMORY_ADDRESS_MASK     0xfffffff0
#define PCI_ADDRESS_ROM_ADDRESS_MASK        0xfffff800

#define PCI_TYPE_32BIT      0
#define PCI_TYPE_20BIT      2
#define PCI_TYPE_64BIT      4


/* Error Code */
#define ERR_PCI_POWERUP     (0x10)


INT  PCIBusInit(VOID);
BOOL PCIScanDevice(PPCI_DEV_INFO_EX pinfo);
INT  PCICfg(PPCI_DEV_INFO_EX pinfo);

#endif /* _NUC900_PCI_H */